package com.lcf.app.es.repository;

import com.lcf.app.es.model.Article;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.annotations.Query;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;

import java.util.List;

/**
 * @author ChenFei
 * @date 2021/12/8
 * <p>
 * 可以使用的Repository：
 * <p>
 * ReactiveRepository
 * <p>
 * ReactiveCrudRepository
 * <p>
 * ReactiveSortingRepository
 */
public interface ArticleRepository extends ElasticsearchRepository<Article, String> {

    /**
     * 根据方法名进行查询,对方法名要求比较严格
     * eg：
     * And
     * <p>
     * findByNameAndPrice
     * <p>
     * { "query" : { "bool" : { "must" : [ { "query_string" : { "query" : "?", "fields" : [ "name" ] } }, { "query_string" : { "query" : "?", "fields" : [ "price" ] } } ] } }}
     * <p>
     * Or
     * <p>
     * findByNameOrPrice
     * <p>
     * { "query" : { "bool" : { "should" : [ { "query_string" : { "query" : "?", "fields" : [ "name" ] } }, { "query_string" : { "query" : "?", "fields" : [ "price" ] } } ] } }}
     * <p>
     * Is
     * <p>
     * findByName
     * <p>
     * { "query" : { "bool" : { "must" : [ { "query_string" : { "query" : "?", "fields" : [ "name" ] } } ] } }}
     * <p>
     * Not
     * <p>
     * findByNameNot
     * <p>
     * { "query" : { "bool" : { "must_not" : [ { "query_string" : { "query" : "?", "fields" : [ "name" ] } } ] } }}
     * <p>
     * Between
     * <p>
     * findByPriceBetween
     * <p>
     * { "query" : { "bool" : { "must" : [ {"range" : {"price" : {"from" : ?, "to" : ?, "include_lower" : true, "include_upper" : true } } } ] } }}
     * <p>
     * LessThan
     * <p>
     * findByPriceLessThan
     * <p>
     * { "query" : { "bool" : { "must" : [ {"range" : {"price" : {"from" : null, "to" : ?, "include_lower" : true, "include_upper" : false } } } ] } }}
     * <p>
     * LessThanEqual
     * <p>
     * findByPriceLessThanEqual
     * <p>
     * { "query" : { "bool" : { "must" : [ {"range" : {"price" : {"from" : null, "to" : ?, "include_lower" : true, "include_upper" : true } } } ] } }}
     * <p>
     * GreaterThan
     * <p>
     * findByPriceGreaterThan
     * <p>
     * { "query" : { "bool" : { "must" : [ {"range" : {"price" : {"from" : ?, "to" : null, "include_lower" : false, "include_upper" : true } } } ] } }}
     * <p>
     * GreaterThanEqual
     * <p>
     * findByPriceGreaterThan
     * <p>
     * { "query" : { "bool" : { "must" : [ {"range" : {"price" : {"from" : ?, "to" : null, "include_lower" : true, "include_upper" : true } } } ] } }}
     * <p>
     * Before
     * <p>
     * findByPriceBefore
     * <p>
     * { "query" : { "bool" : { "must" : [ {"range" : {"price" : {"from" : null, "to" : ?, "include_lower" : true, "include_upper" : true } } } ] } }}
     * <p>
     * After
     * <p>
     * findByPriceAfter
     * <p>
     * { "query" : { "bool" : { "must" : [ {"range" : {"price" : {"from" : ?, "to" : null, "include_lower" : true, "include_upper" : true } } } ] } }}
     * <p>
     * Like
     * <p>
     * findByNameLike
     * <p>
     * { "query" : { "bool" : { "must" : [ { "query_string" : { "query" : "?*", "fields" : [ "name" ] }, "analyze_wildcard": true } ] } }}
     * <p>
     * StartingWith
     * <p>
     * findByNameStartingWith
     * <p>
     * { "query" : { "bool" : { "must" : [ { "query_string" : { "query" : "?*", "fields" : [ "name" ] }, "analyze_wildcard": true } ] } }}
     * <p>
     * EndingWith
     * <p>
     * findByNameEndingWith
     * <p>
     * { "query" : { "bool" : { "must" : [ { "query_string" : { "query" : "*?", "fields" : [ "name" ] }, "analyze_wildcard": true } ] } }}
     * <p>
     * Contains/Containing
     * <p>
     * findByNameContaining
     * <p>
     * { "query" : { "bool" : { "must" : [ { "query_string" : { "query" : "*?*", "fields" : [ "name" ] }, "analyze_wildcard": true } ] } }}
     * <p>
     * In （当注释为 FieldType.Keyword 时）
     * <p>
     * findByNameIn(Collection<String>names)
     * <p>
     * { "query" : { "bool" : { "must" : [ {"bool" : {"must" : [ {"terms" : {"name" : ["?","?"]}} ] } } ] } }}
     * <p>
     * In
     * <p>
     * findByNameIn(Collection<String>names)
     * <p>
     * { "query": {"bool": {"must": [{"query_string":{"query": "\"?\" \"?\"", "fields": ["name"]}}]}}}
     * <p>
     * NotIn （当注释为 FieldType.Keyword 时）
     * <p>
     * findByNameNotIn(Collection<String>names)
     * <p>
     * { "query" : { "bool" : { "must" : [ {"bool" : {"must_not" : [ {"terms" : {"name" : ["?","?"]}} ] } } ] } }}
     * <p>
     * NotIn
     * <p>
     * findByNameNotIn(Collection<String>names)
     * <p>
     * {"query": {"bool": {"must": [{"query_string": {"query": "NOT(\"?\" \"?\")", "fields": ["name"]}}]}}}
     * <p>
     * True
     * <p>
     * findByAvailableTrue
     * <p>
     * { "query" : { "bool" : { "must" : [ { "query_string" : { "query" : "true", "fields" : [ "available" ] } } ] } }}
     * <p>
     * False
     * <p>
     * findByAvailableFalse
     * <p>
     * { "query" : { "bool" : { "must" : [ { "query_string" : { "query" : "false", "fields" : [ "available" ] } } ] } }}
     * <p>
     * OrderBy
     * <p>
     * findByAvailableTrueOrderByNameDesc
     * <p>
     * { "query" : { "bool" : { "must" : [ { "query_string" : { "query" : "true", "fields" : [ "available" ] } } ] } }, "sort":[{"name":{"order":"desc"}}] }
     * <p>
     * Exists
     * <p>
     * findByNameExists
     * <p>
     * {"query":{"bool":{"must":[{"exists":{"field":"name"}}]}}}
     * <p>
     * IsNull
     * <p>
     * findByNameIsNull
     * <p>
     * {"query":{"bool":{"must_not":[{"exists":{"field":"name"}}]}}}
     * <p>
     * IsNotNull
     * <p>
     * findByNameIsNotNull
     * <p>
     * {"query":{"bool":{"must":[{"exists":{"field":"name"}}]}}}
     * <p>
     * IsEmpty
     * <p>
     * findByNameIsEmpty
     * <p>
     * {"query":{"bool":{"must":[{"bool":{"must":[{"exists":{"field":"name"}}],"must_not":[{"wildcard":{"name":{"wildcard":"*"}}}]}}]}}}
     * <p>
     * IsNotEmpty
     * <p>
     * findByNameIsNotEmpty
     * <p>
     * {"query":{"bool":{"must":[{"wildcard":{"name":{"wildcard":"*"}}}]}}}
     *
     * @return
     */
    List<Article> findByContentContaining(String content);

    /**
     * 方法返回值可定义的类型
     * <p>
     * List<T>
     * <p>
     * Stream<T>
     * <p>
     * SearchHits<T>
     * <p>
     * List<SearchHit<T>>
     * <p>
     * Stream<SearchHit<T>>
     * <p>
     * SearchPage<T>
     */

    /**
     * 使用注解查询
     *
     * @param title
     * @return
     */
    @Query("{\"match\": {\"title\": {\"query\": \"?0\"}}}")
    Page<Article> listByTitle(String title, Pageable pageable);

}
